package com.randev.snapcamera;

import java.io.File;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.SQLException;
import android.graphics.Color;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Messenger;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.randev.snap.MainMenuActivity;
import com.randev.snap.R;
import com.randev.snapconfig.Config;
import com.randev.snapdb.AlbumDetails;
import com.randev.snapservices.LocationAddressService;

public class CameraAlbumDetails extends Activity implements OnClickListener {
	
	private final String TAG = "CameraAlbumDetails";
	
	private static TextView tViewGeoLocation;
	private EditText txtAlbumTitle;
	private EditText txtAlbumDescription;
	private Button btnSaveDetails;
	private static final int FIVE_SECONDS = 1000 * 5;
	private Location oldLocation, newLocation, bestLocation;
	private LocationManager locationManager;
	private String albumId = "";	
	private boolean firstTime = true;
	private static ProgressBar pBarLocationStatus;
	private static String previousLocation = "";
	private long result = -1;
	private AlertDialog.Builder alertDialog;
	
	
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		setContentView(R.layout.album_details);
		
		tViewGeoLocation = (TextView) findViewById(R.id.tvGeoLocation);
		txtAlbumTitle = (EditText) findViewById(R.id.etAlbumTitle);
		txtAlbumDescription = (EditText) findViewById(R.id.etAlbumDescription);
		btnSaveDetails = (Button) findViewById(R.id.bSave);
		locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
		pBarLocationStatus = (ProgressBar) findViewById(R.id.pbLocationLoading);
		pBarLocationStatus.setBackgroundColor(Color.parseColor(CameraAlbumDetails.this.getString(R.color.blue_background)));

		alertDialog = new AlertDialog.Builder(CameraAlbumDetails.this);

		
		btnSaveDetails.setOnClickListener(this);
		tViewGeoLocation.setOnClickListener(this);
		tViewGeoLocation.setClickable(true);
		getDataFromPreviousActivity();
		
		if (!isNetworkAvailable()) {
			pBarLocationStatus.setVisibility(View.INVISIBLE);
			tViewGeoLocation.setText(CameraAlbumDetails.this.getString(R.string.info_click_to_add_details));
		} else {
			pBarLocationStatus.setVisibility(View.VISIBLE);
			tViewGeoLocation.setVisibility(View.INVISIBLE);
			setLocation();
		}
		
		
		
	}

	private void setLocation() {
		try {
			locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
			if (isNetworkAvailable()) {
				locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
			}
		}catch (SecurityException e) {
			Log.w(TAG, "Error Refreshing location: " + e.toString());
		} catch (IllegalArgumentException e) {
			Log.w(TAG, "Error Refreshing location: " + e.toString());
		} catch (RuntimeException e) {
			Log.w(TAG, "Error Refreshing location: " + e.toString());
		}
	}

	private void getDataFromPreviousActivity() {
		try {
			Bundle bundle = getIntent().getExtras();
			albumId = bundle.getString(Config.FOLDER_ID);
		} catch (Exception e) {
			Log.w(TAG, "Error getting data from previos activity: " + e.toString());
		}
	}

	@Override
	public void onClick(View v) {
		
		int id = v.getId();
		
		switch (id) {
		case R.id.bSave:
			locationManager.removeUpdates(locationListener);
			
			if (checkFields()) {
				String latitude = String.valueOf(bestLocation.getLatitude());
				String longitude = String.valueOf(bestLocation.getLongitude());
				String title = txtAlbumTitle.getText().toString();
				String description = txtAlbumDescription.getText().toString();
				String location = tViewGeoLocation.getText().toString();
				saveAlbumDetails(latitude, longitude, title, description, location);
			} else {
				alertDialog.setTitle(CameraAlbumDetails.this.getString(R.string.warning));
				TextView tViewAlert = new TextView(CameraAlbumDetails.this);
				tViewAlert.setGravity(Gravity.CENTER_HORIZONTAL);
				tViewAlert.setText(CameraAlbumDetails.this.getString(R.string.info_form_not_complete));
				tViewAlert.setHeight(90);
				alertDialog.setView(tViewAlert);
				alertDialog.setPositiveButton(CameraAlbumDetails.this.getString(R.string.yes), new DialogInterface.OnClickListener() {
					
					@Override
					public void onClick(DialogInterface dialog, int which) {
						dialog.dismiss();
						String latitude = String.valueOf(bestLocation.getLatitude());
						String longitude = String.valueOf(bestLocation.getLongitude());
						String title = txtAlbumTitle.getText().toString();
						String description = txtAlbumDescription.getText().toString();
						String location = tViewGeoLocation.getText().toString();
						saveAlbumDetails(latitude, longitude, title, description, location);
						
					}
				});
				alertDialog.setNegativeButton(CameraAlbumDetails.this.getString(R.string.no), new DialogInterface.OnClickListener() {
					
					@Override
					public void onClick(DialogInterface dialog, int which) {
						dialog.dismiss();
					}
				});
				alertDialog.show();
				
			}
			
			
			break;
		case R.id.tvGeoLocation:
			try {
				locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, FIVE_SECONDS, 0, locationListener);
				if (isNetworkAvailable()) {
					locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
				} else {
					alertDialog.setTitle(CameraAlbumDetails.this.getString(R.string.alert));
					final EditText txtLocation = new EditText(CameraAlbumDetails.this);
					String geoLocation = tViewGeoLocation.getText().toString();
					if (!geoLocation.isEmpty()) {
						txtLocation.setText(geoLocation);
					} else {
						txtLocation.setHint(CameraAlbumDetails.this.getString(R.string.enter_location));

					}
					txtLocation.setMaxLines(4);
					txtLocation.setMinLines(1);
					alertDialog.setView(txtLocation);
					alertDialog.setPositiveButton(CameraAlbumDetails.this.getString(R.string.okay), new DialogInterface.OnClickListener() {
						
						@Override
						public void onClick(DialogInterface dialog, int which) {
							dialog.dismiss();
							String loc = txtLocation.getText().toString();
							tViewGeoLocation.setText(loc);
							
							
						}
					});
					alertDialog.show();
				}
			}catch (SecurityException e) {
				Log.w(TAG, "Error Refreshing location: " + e.toString());
			} catch (IllegalArgumentException e) {
				Log.w(TAG, "Error Refreshing location: " + e.toString());
			} catch (RuntimeException e) {
				Log.w(TAG, "Error Refreshing location: " + e.toString());
			}
			break;
		}
	}
	
	private boolean checkFields() {
		boolean check = false;
		if (!txtAlbumTitle.getText().toString().isEmpty()) {
			if (!txtAlbumDescription.getText().toString().isEmpty()) {
				if (!tViewGeoLocation.getText().toString().isEmpty()) {
					check = true;
				} else {
					check = true;
				}
			} else {
				check = false;
			}
		} else {
			check = false;
		}
		return check;
	}

	private void saveAlbumDetails(final String latitude, final String longitude, final String title, final String description, final String location) {
		result = -1;
		
		try {
			
			if (!checkFolderExists(title)) {
				if (renameFolder(title, "Set " + albumId)) {
					AlbumDetails albumDetails = new AlbumDetails(this);
					albumDetails.openWritableDatabase();
					result = albumDetails.insertAlbumDetails(albumId, title, description, longitude, latitude, location);
					albumDetails.closeDatabase();
					
					if (result != -1) {
						try {
							Intent  mainMenuIntent = new Intent(CameraAlbumDetails.this, MainMenuActivity.class);
							finish();
							startActivity(mainMenuIntent);
						} catch (ActivityNotFoundException e) {
							Log.w(TAG, "Unable to start mainmenu activity: " + e.toString());
						}
					} else {
						alertDialog.setTitle(CameraAlbumDetails.this.getString(R.string.error));
						TextView tViewalertError = new TextView(CameraAlbumDetails.this);
						tViewalertError.setGravity(Gravity.CENTER_HORIZONTAL);
						tViewalertError.setText(CameraAlbumDetails.this.getString(R.string.error_saving_album_details));
						tViewalertError.setHeight(90);
						alertDialog.setView(tViewalertError);
						alertDialog.setPositiveButton(CameraAlbumDetails.this.getString(R.string.okay), new DialogInterface.OnClickListener() {
							
							@Override
							public void onClick(DialogInterface dialog, int which) {
								try {
									Intent  mainMenuIntent = new Intent(CameraAlbumDetails.this, MainMenuActivity.class);
									finish();
									startActivity(mainMenuIntent);
								} catch (ActivityNotFoundException e) {
									Log.w(TAG, "Unable to start mainmenu activity: " + e.toString());
								}
								
							}
						});
						alertDialog.show();
						Log.w(TAG, "RESult" + result);
					}
				} else {
					Log.w(TAG, "Error Renaming file");
					alertDialog.setTitle(CameraAlbumDetails.this.getString(R.string.warning));
					TextView tViewFolderExist = new TextView(CameraAlbumDetails.this);
					tViewFolderExist.setGravity(Gravity.CENTER_VERTICAL);
					tViewFolderExist.setText(CameraAlbumDetails.this.getString(R.string.error_renaiming_file));
					tViewFolderExist.setHeight(90);
					alertDialog.setView(tViewFolderExist);
					alertDialog.setPositiveButton(CameraAlbumDetails.this.getString(R.string.okay), new DialogInterface.OnClickListener() {
						
						@Override
						public void onClick(DialogInterface dialog, int which) {
							dialog.dismiss();
							AlbumDetails albumDetails = new AlbumDetails(CameraAlbumDetails.this);
							albumDetails.openWritableDatabase();
							result = albumDetails.insertAlbumDetails(albumId, "Set " + albumId, description, longitude, latitude, location);
							albumDetails.closeDatabase();
							
							
							if (result != -1) {
								try {
									Intent  mainMenuIntent = new Intent(CameraAlbumDetails.this, MainMenuActivity.class);
									finish();
									startActivity(mainMenuIntent);
								} catch (ActivityNotFoundException e) {
									Log.w(TAG, "Unable to start mainmenu activity: " + e.toString());
								}
							} else {
								alertDialog.setTitle(CameraAlbumDetails.this.getString(R.string.error));
								TextView tViewalertError = new TextView(CameraAlbumDetails.this);
								tViewalertError.setGravity(Gravity.CENTER_HORIZONTAL);
								tViewalertError.setText(CameraAlbumDetails.this.getString(R.string.error_saving_album_details));
								tViewalertError.setHeight(90);
								alertDialog.setView(tViewalertError);
								alertDialog.setPositiveButton(CameraAlbumDetails.this.getString(R.string.okay), new DialogInterface.OnClickListener() {
									
									@Override
									public void onClick(DialogInterface dialog, int which) {
										try {
											Intent  mainMenuIntent = new Intent(CameraAlbumDetails.this, MainMenuActivity.class);
											finish();
											startActivity(mainMenuIntent);
										} catch (ActivityNotFoundException e) {
											Log.w(TAG, "Unable to start mainmenu activity: " + e.toString());
										}
										
									}
								});
								alertDialog.show();
								Log.w(TAG, "RESult" + result);
							}
							
						}
					});
					alertDialog.show();
				}
			} else {
				Log.w(TAG, "folder exists");
				alertDialog.setTitle(CameraAlbumDetails.this.getString(R.string.warning));
				TextView tViewFolderExist = new TextView(CameraAlbumDetails.this);
				tViewFolderExist.setGravity(Gravity.CENTER_VERTICAL);
				tViewFolderExist.setText(CameraAlbumDetails.this.getString(R.string.info_title_already_exists));
				tViewFolderExist.setHeight(90);
				alertDialog.setView(tViewFolderExist);
				alertDialog.setPositiveButton(CameraAlbumDetails.this.getString(R.string.okay), new DialogInterface.OnClickListener() {
					
					@Override
					public void onClick(DialogInterface dialog, int which) {
						dialog.dismiss();
					}
				});
				alertDialog.show();
			}
		} catch (SQLException e) {
			Log.w(TAG, "Error Saving data to DB: " + e.toString());
		} catch (Exception e) {
			Log.w(TAG, "Error saveAlbumDetails: " + e.toString());
		}
	}

	private LocationListener locationListener = new LocationListener() {
	    public void onLocationChanged(Location location) {
	    	
	    	if (firstTime) {
	    		oldLocation = location;
	    		newLocation = location;
	    		firstTime = false;
	    	}
	    	
	    	oldLocation = newLocation;
	    	newLocation = location;
	    	
	    	boolean betterLocation = isBetterLocation(oldLocation, newLocation);
	    	
	    	if (betterLocation){
	    		bestLocation = oldLocation;
	    	} else {
	    		bestLocation = newLocation;
	    	}
	    	Messenger addressMessenger = new Messenger(addressMessengerHandler);
	    	Object[] locationAsynDetails = new Object[3];
	    	Bundle bundle = new Bundle();
	    	bundle.putString("Latitude", String.valueOf(bestLocation.getLatitude()));
	    	bundle.putString("Longitude", String.valueOf(bestLocation.getLongitude()));
	    	
	    	locationAsynDetails[0] = addressMessenger;
	    	locationAsynDetails[1] = bundle;
	    	locationAsynDetails[2] = CameraAlbumDetails.this;
	    	
	    	
	    	new LocationAddressService().execute(locationAsynDetails);
	    	
	    }

	    public void onStatusChanged(String provider, int status, Bundle extras) {
	    	
	    }

	    public void onProviderEnabled(String provider) {
	    	
	    }

	    public void onProviderDisabled(String provider) {
	    	
	    }
	};

	private boolean isBetterLocation(Location location, Location currentBestLocation) {
		pBarLocationStatus.setVisibility(View.VISIBLE);
		tViewGeoLocation.setVisibility(View.INVISIBLE);
		if (currentBestLocation == null) {
			return true;
		}

		long timeDelta = location.getTime() - currentBestLocation.getTime();
		boolean isSignificantlyNewer = timeDelta > FIVE_SECONDS;
		boolean isSignificantlyOlder = timeDelta < -FIVE_SECONDS;
		boolean isNewer = timeDelta > 0;

		if (isSignificantlyNewer) {
			return true;
		} else if (isSignificantlyOlder) {
			return false;
		}

		int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation
				.getAccuracy());
		boolean isLessAccurate = accuracyDelta > 0;
		boolean isMoreAccurate = accuracyDelta < 0;
		boolean isSignificantlyLessAccurate = accuracyDelta > 200;

		boolean isFromSameProvider = isSameProvider(location.getProvider(),
				currentBestLocation.getProvider());

		if (isMoreAccurate) {
			return true;
		} else if (isNewer && !isLessAccurate) {
			return true;
		} else if (isNewer && !isSignificantlyLessAccurate
				&& isFromSameProvider) {
			return true;
		}
		return false;
	}

	private boolean isSameProvider(String provider1, String provider2) {
		if (provider1 == null) {
			return provider2 == null;
		}
		return provider1.equals(provider2);
	}
	
	private static Handler addressMessengerHandler = new Handler() {
		public void handleMessage(Message message) {
			Bundle resultFromLocationAddressService = message.getData();
			
			if (message.arg1 == 1) {
				pBarLocationStatus.setVisibility(View.VISIBLE);
				tViewGeoLocation.setVisibility(View.INVISIBLE);
			} else if (message.arg1 == 2) {
				pBarLocationStatus.setVisibility(View.INVISIBLE);
				tViewGeoLocation.setVisibility(View.VISIBLE);
			}
			
			String address = resultFromLocationAddressService.getString(Config.ADDRESS);

			if (address != ""  && address != null) {
				Log.w("address from G maps: ", address);
				tViewGeoLocation.setText(address);
				previousLocation = address;
			} else {
				tViewGeoLocation.setText(previousLocation);
			}
		};
	};
	
	public boolean onKeyDown(int keyCode, KeyEvent event)  {
	    if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
	    	alertDialog.setTitle(CameraAlbumDetails.this.getString(R.string.alert));
	    	TextView tViewFolderExist = new TextView(CameraAlbumDetails.this);
			tViewFolderExist.setGravity(Gravity.CENTER_VERTICAL);
			tViewFolderExist.setText(CameraAlbumDetails.this.getString(R.string.info_discard_or_save));
			tViewFolderExist.setHeight(90);
			alertDialog.setView(tViewFolderExist);
			alertDialog.setPositiveButton(CameraAlbumDetails.this.getString(R.string.yes), new DialogInterface.OnClickListener() {
				
				@Override
				public void onClick(DialogInterface dialog, int which) {
					dialog.dismiss();
					try  {
						File fileToDelete = new File(Config.HOME_DIRECTORY + File.separator + "Set " + albumId);
						if (fileToDelete.exists()) {
							String[] imagesToDelete = fileToDelete.list();
							for (String image: imagesToDelete) {
								File imageToDelete = new File(fileToDelete + File.separator + image);
								imageToDelete.delete();
							}
							fileToDelete.delete();
						}
						
						Intent  albumDetailsIntent = new Intent(CameraAlbumDetails.this, MainMenuActivity.class);
						finish();
						startActivity(albumDetailsIntent);
						
					} catch (ActivityNotFoundException e) {
						Log.w(TAG, "Unable to start MainMenu activity: " + e.toString());
					} catch (Exception e) {
						Log.w(TAG, "Error deleting files: " + e.toString());
					}
				}
			});
			alertDialog.setNegativeButton(CameraAlbumDetails.this.getString(R.string.no), new DialogInterface.OnClickListener() {
				
				@Override
				public void onClick(DialogInterface dialog, int which) {
					dialog.dismiss();
				}
			});
			alertDialog.show();
	    }
	    return super.onKeyDown(keyCode, event);
	}
	
	private boolean isNetworkAvailable() {
	    ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
	    NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
	    return networkInfo != null && networkInfo.isConnectedOrConnecting();
	}
	
	private boolean checkFolderExists(String title) {
		boolean folderExists = false;
		File parentFile = new File(Config.HOME_DIRECTORY);
		
		String[] fileNames = parentFile.list();
		
		for (String fileName: fileNames) {
			if (fileName.contentEquals(title)) {
				folderExists = true;
			}
		}
		return folderExists;
	}
	
	private boolean renameFolder(String title, String oldFolderName) {
		boolean renameSuccess = false;
		
		try {
			String oldFilePath = Config.HOME_DIRECTORY + File.separator + oldFolderName;
			File oldFileName = new File(oldFilePath);
			String newFilePath = Config.HOME_DIRECTORY  + File.separator + title;
			File newfile = new File(newFilePath);
			renameSuccess = oldFileName.renameTo(newfile);
		} catch  (Exception e) {
			Log.w(TAG, "error renaming file: " + e.toString());
		}
		
		return renameSuccess;
		
	}
	
	
}